package fr.cephb.operonj.tools.cmdline;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;

import com.sleepycat.je.Cursor;
import com.sleepycat.je.DatabaseConfig;
import com.sleepycat.je.DatabaseEntry;
import com.sleepycat.je.DatabaseException;
import com.sleepycat.je.LockMode;
import com.sleepycat.je.OperationStatus;

import fr.cephb.operonj.core.bio.Build;
import fr.cephb.operonj.core.db.database.BuildDB;

public class BuildDump extends AbstractApplication
	{
	private File fileOut=null;
	
	@Override
	protected void usage(PrintStream out)
		{
		super.usage(out);
		out.println("Options:");
		out.println(" -o <fileout>");
		}
	
	@Override
	protected int processArg(String[] args, int optind)
		{
		int n= super.processArg(args, optind);
		if(n!=-1) return n;
		if(args[optind].equals("-o"))
			{
			this.fileOut=new File(args[++optind]);
			return optind;
			}
		return -1;
		}
	
	private int run(String args[]) throws IOException,DatabaseException,XMLStreamException
		{
		Cursor c=null;
		DatabaseEntry key= new DatabaseEntry();
		DatabaseEntry data= new DatabaseEntry();
		int optind= processArgs(args);
		if(optind!=args.length)
			{
			System.err.println("too many arguments");
			return -1;
			}
		
		OutputStream w=(
			fileOut==null?
			System.out:
			new FileOutputStream(this.fileOut)
			);
		
		open();
		DatabaseConfig cfgConfig= new DatabaseConfig();
		cfgConfig.setAllowCreate(false);
		cfgConfig.setReadOnly(true);
		BuildDB db=new BuildDB(getEnvironment(), null, null, cfgConfig);
		XMLStreamWriter out=XMLOutputFactory.newInstance().createXMLStreamWriter(w);
		
		out.writeStartDocument("UTF-8","1.0");
		
		
		try
			{
			out.writeStartElement("builds");
			
			JAXBContext context = JAXBContext.newInstance(Build.class);
			Marshaller marshaller=context.createMarshaller();
			marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
			marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
			marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true);
			//marshaller.setProperty(Marshaller.JAXB_SCHEMA_LOCATION, "");
			c=db.openCursor(null);
			while(c.getNext(key, data, LockMode.DEFAULT)==OperationStatus.SUCCESS)
				{
				Build build= db.getValueBinding().entryToObject(data);
				marshaller.marshal(build, out);
				}
			out.writeEndElement();
			out.writeEndDocument();
			out.flush();
			out.close();
			}
		catch (JAXBException e)
			{
			throw new RuntimeException(e);
			}
		catch (XMLStreamException e)
			{
			throw e;
			}
		finally
			{
			c.close();
			}
		db.close();
		close();
		return 0;
		}
	
	
	public static void main(String[] args)
		{
		try
			{
			BuildDump app= new BuildDump();
			app.run(args);
			}
		catch (Exception err)
			{
			err.printStackTrace();
			}
		}
	}
